
class Standard_VHD_File

  def initialize( file_in )
    @file = file_in
  end

  def write_beginning

    # create headers
    @file.print("library ieee;\n")
    @file.print("use ieee.std_logic_1164.all\n")
    @file.print("use ieee.numeric_std.all\n")
    @file.print("\n")

    # declare testbench entity
    @file.print("entity generated_controller_tb is\n")
    @file.print("end entity generated_controller_tb;\n")
    @file.print("\n")

    # open architecture statement
    @file.print("architecture tb of generated_controller_tb is\n\n")

  end

  def write_components

    # generate comment header for components
    @file.print("\t------------------------------------------------------------------------------------------\n");
    @file.print("\t--\n")
    @file.print("\t-- components\n")
    @file.print("\t--\n")
    @file.print("\t-- components used are defined here\n")
    @file.print("\t--\n")
    @file.print("\t------------------------------------------------------------------------------------------\n\n");

    # generate component listings
    @file.print("\tcomponent link_controller is\n\n")
    @file.print("\t\tport ( clk               : in  std_logic;\n")
    @file.print("\t\t       host_address      : in  std_logic_vector(31 DownTo 0);\n")
    @file.print("\t\t       data_in_n         : in  std_logic;\n")
    @file.print("\t\t       data_in_ne        : in  std_logic;\n")
    @file.print("\t\t       data_in_nw        : in  std_logic;\n")
    @file.print("\t\t       data_in_s         : in  std_logic;\n")
    @file.print("\t\t       data_in_se        : in  std_logic;\n")
    @file.print("\t\t       data_in_sw        : in  std_logic;\n")
    @file.print("\t\t       data_in_e         : in  std_logic;\n")
    @file.print("\t\t       data_in_w         : in  std_logic;\n")
    @file.print("\t\t       data_out_n        : out std_logic;\n")
    @file.print("\t\t       data_out_ne       : out std_logic;\n")
    @file.print("\t\t       data_out_nw       : out std_logic;\n")
    @file.print("\t\t       data_out_s        : out std_logic;\n")
    @file.print("\t\t       data_out_se       : out std_logic;\n")
    @file.print("\t\t       data_out_sw       : out std_logic;\n")
    @file.print("\t\t       data_out_e        : out std_logic;\n")
    @file.print("\t\t       data_out_w        : out std_logic;\n")
    @file.print("\t\t     );\n\n")
    @file.print("\tend component;\n\n")

    @file.print("\tcomponent link_controller is \n\n")
    @file.print("\t\tport ( link_a    : std_logic;\n")
    @file.print("\t\t       link_b    : std_logic;\n")
    @file.print("\t\t       or_out    : std_logic;\n")
    @file.print("\t\t     );\n\n")
    @file.print("\tend component;\n\n")

  end

  def write_global_signals

    # generate comment header for global signals
    @file.print("\t------------------------------------------------------------------------------------------\n");
    @file.print("\t--\n")
    @file.print("\t-- global signals\n")
    @file.print("\t--\n")
    @file.print("\t-- all global signals used across controllers are defined here\n")
    @file.print("\t-- \n")
    @file.print("\t------------------------------------------------------------------------------------------\n\n");

    @file.print("\t signal controller_clk                          : std_logic;\n\n")

  end

  def write_active_links( link_array )

    @file.print("\t------------------------------------------------------------------------------------------\n");
    @file.print("\t--\n")
    @file.print("\t-- link signals\n")
    @file.print("\t--\n")
    @file.print("\t-- physical link signals for active controllers\n")
    @file.print("\t--\n")
    @file.print("\t------------------------------------------------------------------------------------------\n\n");

    # create link strings for printing to @file
    link_array.each { |link|
      @file.print( line_up_scribble( "\tsignal physical_link_#{link}", ": std_logic;\n", 50 ) )
    }

    @file.print("\n\n")

  end

  def write_active_links_to_boundaries( link_array )

    @file.print("\t------------------------------------------------------------------------------------------\n");
    @file.print("\t--\n")
    @file.print("\t-- physical links between boundaries and active links\n")
    @file.print("\t--\n")
    @file.print("\t--\n")
    @file.print("\t--\n")
    @file.print("\t------------------------------------------------------------------------------------------\n\n");

    link_array.each { |link|
      @file.print( line_up_scribble( "\tsignal physical_link_#{link}", ": std_logic;\n", 50 ) )
    }

    @file.print("\n\n")

  end
    
  def write_loop_back_signals( link_array )

    @file.print("\t------------------------------------------------------------------------------------------\n");
    @file.print("\t--\n")
    @file.print("\t-- loop back link signals\n")
    @file.print("\t--\n")
    @file.print("\t-- loop back link signals for boundary controllers\n")
    @file.print("\t--\n")
    @file.print("\t------------------------------------------------------------------------------------------\n\n");

    link_array.each { |link|
      @file.print( line_up_scribble( "\tsignal p_l_loop_#{link}", ": std_logic;\n", 50 ) )
    }

    @file.print("\n\n")

  end

  def write_controller_signals_header

    @file.print("\t------------------------------------------------------------------------------------------\n");
    @file.print("\t--\n")
    @file.print("\t-- controller signals\n")
    @file.print("\t--\n")
    @file.print("\t-- all controller signals defined here\n")
    @file.print("\t--\n")
    @file.print("\t------------------------------------------------------------------------------------------\n\n");

  end

  def write_controller_signals( controller_array )

    controller_array.each { |controller|

      @file.print("\t-- controller #{controller[0]} signals\n")
      @file.print(line_up_scribble( "\tsignal link_#{controller[0]}_address",": std_logic_vector(31 DownTo 0);\n",50))
      @file.print(line_up_scribble( "\tsignal link_#{controller[0]}_pixel", ": std_logic;\n", 50 ) )
      @file.print(line_up_scribble( "\tsignal link_#{controller[0]}_complete", ": std_logic;\n", 50 ) )
      @file.print(line_up_scribble( "\tsignal link_#{controller[0]}_f_label",": std_logic_vector(31 DownTo 0);\n",50))
      @file.print(line_up_scribble( "\tsignal link_#{controller[0]}_n", ": std_logic;\n", 50 ) )
      @file.print(line_up_scribble( "\tsignal link_#{controller[0]}_ne", ": std_logic;\n", 50 ) )
      @file.print(line_up_scribble( "\tsignal link_#{controller[0]}_nw", ": std_logic;\n", 50 ) )
      @file.print(line_up_scribble( "\tsignal link_#{controller[0]}_s", ": std_logic;\n", 50 ) )
      @file.print(line_up_scribble( "\tsignal link_#{controller[0]}_se", ": std_logic;\n", 50 ) )
      @file.print(line_up_scribble( "\tsignal link_#{controller[0]}_sw", ": std_logic;\n", 50 ) )
      @file.print(line_up_scribble( "\tsignal link_#{controller[0]}_e", ": std_logic;\n", 50 ) )
      @file.print(line_up_scribble( "\tsignal link_#{controller[0]}_w", ": std_logic;\n", 50 ) )

      @file.print("\n\n")
      
    }

  end

  def write_controller_header

    @file.print("\t------------------------------------------------------------------------------------------\n");
    @file.print("\t--\n")
    @file.print("\t-- controllers\n")
    @file.print("\t--\n")
    @file.print("\t-- all controllers are set up here\n")
    @file.print("\t--\n")
    @file.print("\t------------------------------------------------------------------------------------------\n\n");

  end

  def write_controllers( controllers )

    for controller in controllers

      tempString = line_up_scribble( "\tlink_controller_#{controller[0]}", ": link_controller port map (", 30 )
      tempString = line_up_scribble( tempString, "controller_clk,", 60 )

      @file.print( tempString + "\n" )
      @file.print( line_up_scribble( "\t", "link_#{controller[0]}_address,\n", 60 ) )
      @file.print( line_up_scribble( "\t", "link_#{controller[0]}_pixel,\n", 60) )
      @file.print( line_up_scribble( "\t", "#{controller[1]},\n", 60) )
      @file.print( line_up_scribble( "\t", "#{controller[2]},\n", 60) )
      @file.print( line_up_scribble( "\t", "#{controller[3]},\n", 60) )
      @file.print( line_up_scribble( "\t", "#{controller[4]},\n", 60) )
      @file.print( line_up_scribble( "\t", "#{controller[5]},\n", 60) )
      @file.print( line_up_scribble( "\t", "#{controller[6]},\n", 60) )
      @file.print( line_up_scribble( "\t", "#{controller[7]},\n", 60) )
      @file.print( line_up_scribble( "\t", "#{controller[8]},\n", 60) )
      @file.print( line_up_scribble( "\t", "link_#{controller[0]}_out_n,\n", 60) )
      @file.print( line_up_scribble( "\t", "link_#{controller[0]}_out_ne,\n", 60) )
      @file.print( line_up_scribble( "\t", "link_#{controller[0]}_out_nw,\n", 60) )
      @file.print( line_up_scribble( "\t", "link_#{controller[0]}_out_s,\n", 60) )
      @file.print( line_up_scribble( "\t", "link_#{controller[0]}_out_se,\n", 60) )
      @file.print( line_up_scribble( "\t", "link_#{controller[0]}_out_sw,\n", 60) )
      @file.print( line_up_scribble( "\t", "link_#{controller[0]}_out_e,\n", 60) )
      @file.print( line_up_scribble( "\t", "link_#{controller[0]}_out_w,\n", 60) )
      @file.print( line_up_scribble( "\t", "link_#{controller[0]}_complete,\n", 60) )
      @file.print( line_up_scribble( "\t", "link_#{controller[0]}_f_label\n", 60) )
      @file.print( line_up_scribble( "\t", ");", 57) )

      @file.print("\n\n")

    end

  end

  def write_active_links_association( link_array )

    @file.print("\t------------------------------------------------------------------------------------------\n");
    @file.print("\t--\n")
    @file.print("\t-- physical links linkage association\n")
    @file.print("\t--\n")
    @file.print("\t--\n")
    @file.print("\t--\n")
    @file.print("\t------------------------------------------------------------------------------------------\n\n");

    

  end

  def write_closing

    # closing the architecture
    @file.print("end tb;\n\n")
   
  end

  def line_up_scribble( start_string, end_string, offset )

    string_buff = start_string

    (offset - start_string.length).times {
      string_buff = string_buff + " "
    }

    string_buff = string_buff + end_string

  end

end
















